#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <linux/in.h>
#include <errno.h>
#include <sys/mman.h>

#define SIZE 1024*20

char* inet_ntoa(struct in_addr in);
struct FileInfo
{
	unsigned int filesize;
	char filename[256];
};


static int fd = 0;
static unsigned int *p = NULL;


int main(void)
{
	//daemon(0,0);//守护进程
	
	//1.创建套接字
	int sockfd =  socket(AF_INET, SOCK_STREAM, 0);//IPPROTO_TCP
	if(sockfd < 0)
	{
		perror("socket fail");
		return -1;
	}

	//2.绑定
	struct sockaddr_in seraddr;                     //跟struct sockaddr结构体大小一样，不过存储格式不同
	memset(&seraddr, 1, sizeof(seraddr));           //初始化为0
	//bzero(&seraddr,(sizeof(seraddr));
	seraddr.sin_family = AF_INET;					//家族协议
	seraddr.sin_port = htons(5678);					//网络字节序
	seraddr.sin_addr.s_addr = htonl(INADDR_ANY);	//自动取本机 IP
	//seraddr.sin_addr.s_addr = inet_addr("192.168.15.218");
	
	int ret = bind(sockfd,(struct sockaddr*)&seraddr,  sizeof(seraddr));
	if(ret < 0)
	{
		perror("bind fail");
		close(sockfd);
	}

	
	ret = listen(sockfd, 5);                        //3.监听
	if(ret < 0)
	{
		perror("listen fail");
		close(sockfd);
		return -1;
	}

	
	struct sockaddr_in clientaddr;
	socklen_t len = sizeof(clientaddr);
	
	struct sockaddr *cliaddr;	
	len = sizeof(srvaddr);
	bzero(&cliaddr, len);
	
	while(1)
	{
		int clientfd = accept(sockfd, (struct sockaddr*)&clientaddr, &len);   //4.接受连接，阻塞
		
		printf("welcome: %s:%hu\n", 
			inet_ntoa(cliaddr.sin_addr),
			ntohs(cliaddr.sin_port));
		if(clientfd < 0)
		{
			perror("accept fail");
		}

		
		printf("lianjie\n");
		struct FileInfo fileinfo;                          //接收文件信息
		read(clientfd, &fileinfo, sizeof(fileinfo));

		printf("%s----%d\n", fileinfo.filename, fileinfo.filesize);
		
		//创建文件--打开-准备写接收的数据
		char recvFilePath[strlen("/netfile")+strlen(fileinfo.filename)+1];       //准备接收的路径和文件名的字符串
		memset(recvFilePath,0, sizeof(recvFilePath));
		
		
		ret = mkdir("/netfile", 00777);                     //创建目录
		if(ret < 0 && errno!=EEXIST)
		{
			continue;
		}
		
		//打包文件路径，即将文件路径和文件名连接在一起
		strcat(recvFilePath, "/netfile/");
		strcat(recvFilePath, fileinfo.filename);
		
		printf("%s\n", recvFilePath);
		FILE *file = fopen(recvFilePath, "w+");
		if(file==NULL)
		{
			perror("creat fail");
		}
			
		
		char buffer[SIZE];
		unsigned int recvsize = 0;
		while(1)
		{
			ret = read(clientfd, buffer, SIZE);
			if(ret <= 0)
				break;
			
			
			fwrite(buffer, ret, 1, file);     //把读到的数据写入文件
			recvsize += ret;
			
			double pos = (double)recvsize*100/(double)fileinfo.filesize ;
			printf("%lf%%\r\n",pos);			
		}
		
		fclose(file);
		close(clientfd);
	}
		
	close(sockfd);
	return 0;
}
